# -*- coding: utf-8 -*-
# @author: edgardeng
# @date:   2021-05-08
# @file:   [websocket] https://websockets.readthedocs.io/en/stable/

import asyncio
import websockets
from websockets.protocol import State

list_client = {}


async def chat(websocket, path):
    print(websocket.extra_headers)
    print(websocket.request_headers)
    id = path[1:]
    list_client[id] = websocket
    await broadcast_msg(id, 'Hello', None)
    # <class 'websockets.server.WebSocketServerProtocol'>a
    try:
        while websocket.state != State.CLOSED:
            # print(websocket.state)
            message = await websocket.recv()
            # await websocket.send(id + ': ok')
            # print(message)
            # async for message in websocket:
            if message == 'exit':
                await broadcast_msg(id, 'Bye', None)
                break
            else:
                await broadcast_msg(id, message, id)
    except websockets.exceptions.ConnectionClosedOK as e:
        print('close')
        print(e)

    del list_client[id]
    print('%s done' % id)
    await websocket.close()


async def broadcast_msg(id, msg, exclude):
    reply = '[Client: %s] said: %s' % (id, msg)

    for key in list_client:
        if key != exclude:
            client = list_client[key]
            if client.state == State.CLOSED:
                continue
            await client.send(reply)


if __name__ == '__main__':
    start_server = websockets.serve(chat, "localhost", 8765)
    asyncio.get_event_loop().run_until_complete(start_server)
    asyncio.get_event_loop().run_forever()
